<template>
	<!-- 核心：使用 scroll-view，开启自定义下拉刷新 -->
	<scroll-view class="cc-paging-scroll-view" 
		scroll-y 
		:refresher-enabled="true" 
		:refresher-triggered="isRefreshing"
		@refresherrefresh="onRefresherRefresh" 
		@refresherpulling="onRefresherPulling"
		@refresherrestore="onRefresherRestore"
		@scrolltolower="onScrollToLower" 
		@scroll="onScroll"		
		:refresher-threshold="refresherThreshold" 
		:upper-threshold="5"
		refresher-background="#f8f8f8" 
		refresher-default-style="none">

		<!-- 自定义下拉刷新区域 -->
		<view class="refresher-container" :style="{'margin-top': -refresherThreshold + 'px'}">
			<!-- 根据状态显示不同内容和动画 -->
			<image v-if="!isRefreshing" :class="leftImageClass" :src="leftImageSrc" />
			<image v-else class="refresher-loading-icon" :src="leftImageSrc" />
			<view class="refresher-text">{{ refresherText }}</view>
		</view>
		
		<!-- 空数据 -->
		<view v-if="showEmpty" class="empty-container">
			<slot name="empty"></slot>
		</view>

		<!-- 内容区域 -->
		<view v-else class="paging-container">
			<!-- 内容插槽：用户列表内容在此渲染 -->
			<slot name="data" :data="innerDataList"></slot>
			<!-- 上拉加载更多状态提示 -->
			<view v-if="showLoadMore" class="load-more-container">
				<text v-if="isLoadingMore" class="load-more-text">正在加载...</text>
				<text v-else-if="noMore" class="load-more-text">我是有底线的</text>
				<text v-else class="load-more-text">上拉加载更多</text>
			</view>
		</view>
		
	</scroll-view>
</template>

<script setup>
	import {
		ref,
		computed,
		watch,
		nextTick
	} from 'vue'
	import Enum from './js/cc-paging-enum'
	import Resource from './js/cc-paging-static'

	const props = defineProps({
		// 外部传入的数据列表，用于 v-model 双向绑定
		modelValue: {
			type: Array,
			default: () => []
		},
		// 每页数据量
		pageSize: {
			type: Number,
			default: 10
		},
		// 是否自动加载第一页数据
		autoLoad: {
			type: Boolean,
			default: true
		},
		// 刷新器样式
		refresherTheme: {
			type: String,
			default: 'black'
		}
	})

	// 定义可触发的事件：update:modelValue, refresh, loadmore
	const emit = defineEmits(['update:modelValue', 'refresh', 'loadmore'])

	// 状态管理
	const refresherThreshold = ref(40); //刷析阀值

	const isRefreshing = ref(false) // 是否正在下拉刷新
	const isFirstPageLoad = ref(true) // 是否首页加数据

	const isLoadingMore = ref(false) // 是否正在上拉加载
	const noMore = ref(false) // 是否已无更多数据
	const currentPage = ref(1) // 当前页码
	const scrollTop = ref(0) // 当前滚动位置


	const refresherText = ref('');
	const leftImageClass = ref('');

	// 组件内部维护的数据列表，用于绑定到 v-model
	const innerDataList = ref([])

	// 刷新的主题
	const innerRefresherTheme = ref({
		title: {
			white: '#efefef',
			black: '#555555'
		},
		arrow: {
			white: Resource.base64ArrowWhite,
			black: Resource.base64Arrow
		},
		flower: {
			white: Resource.base64FlowerWhite,
			black: Resource.base64Flower
		},
		success: {
			white: Resource.base64SuccessWhite,
			black: Resource.base64Success
		},
		indicator: {
			white: '#eeeeee',
			black: '#777777'
		}
	})

	// 刷新状态
	const R = Enum.RefresherStatus;
	const rStatus = ref(R.Default);

	const RefresherConst = {
		[R.Default]: {
			title: '继续下拉刷新',
			refresherImageClass: 'refresher-arrow-icon arrow-down'
		},
		[R.ReleaseToRefresh]: {
			title: '释放立即刷新',
			refresherImageClass: 'refresher-arrow-icon arrow-top'
		},
		[R.Loading]: {
			title: '正在刷新...',
			refresherImageClass: 'refresher-arrow-icon'
		},
		[R.Complete]: {}
	}

	// 左侧图片src
	const leftImageSrc = computed(() => {
		if (rStatus.value == R.Default) {
			return innerRefresherTheme.value.arrow[props.refresherTheme];
		} else if (rStatus.value == R.ReleaseToRefresh) {
			return innerRefresherTheme.value.arrow[props.refresherTheme];
		} else if (rStatus.value == R.Loading) {
			return innerRefresherTheme.value.flower[props.refresherTheme];
		}
	})

	// 显示空数据
	const showEmpty = computed(() => {	
		return !isFirstPageLoad.value && innerDataList.value.length === 0 && !isRefreshing.value
	})
	
	// 显示加载更多
	const showLoadMore = computed(() => {	
		return !isRefreshing.value && !isFirstPageLoad.value
	})

	// 监听外部传入的 modelValue 变化，同步到内部数据
	watch(() => props.modelValue, (newVal) => {
		innerDataList.value = newVal
	}, {
		immediate: true
	})

	// 修改刷新状态
	const updateRefresh = (status) => {
		let c = RefresherConst[status];
		refresherText.value = c.title;
		leftImageClass.value = c.refresherImageClass;
	}

	// 临听刷新状态变化
	watch(() => rStatus, (newVal) => {
		updateRefresh(newVal.value);
	}, {
		deep: true,
		immediate: true
	})

	// 下拉过程事件：根据下拉距离控制箭头旋转和提示文本
	const onRefresherPulling = (e) => {
		// 微信小程序端是 e.detail.dy，H5 端可能是 e.detail.deltaY
		let deltaY = e.detail.dy || e.detail.deltaY
		if (deltaY > refresherThreshold.value) {
			rStatus.value = R.ReleaseToRefresh
		}
		//Math.min(x, y) 
	}

	// 下拉刷新被触发
	const onRefresherRefresh = async () => {
		if (isRefreshing.value) return
		isRefreshing.value = true
		currentPage.value = 1 // 重置为第一页
		noMore.value = false // 重置有无更多数据状态
		rStatus.value = R.Loading //更改态态为刷新状态

		// 触发 refresh 事件，通知父组件刷新数据
		emit('refresh', currentPage.value, props.pageSize)
	}

	// 下拉刷新复位
	const onRefresherRestore = () => {
		rStatus.value = R.Default
		isRefreshing.value = false
	}

	// 滚动触底事件：触发加载更多
	const onScrollToLower = async () => {
		if (isLoadingMore.value || noMore.value || isRefreshing.value) return
		isLoadingMore.value = true
		currentPage.value++
		// 触发 loadmore 事件，通知父组件加载下一页数据
		emit('loadmore', currentPage.value, props.pageSize)
	}

	// 滚动事件记录：记录滚动位置，可用于显示返回顶部按钮等
	const onScroll = (e) => {
		scrollTop.value = e.detail.scrollTop
	}

	// 暴露给父组件的方法：请求完成时调用
	const complete = (newData, total) => {		
		if (currentPage.value === 1) {
			// 下拉刷新，替换数据
			innerDataList.value = newData
		} else {
			// 上拉加载更多，拼接数据
			innerDataList.value = [...innerDataList.value, ...newData]
		}
		// 更新 v-model 绑定的数据
		emit('update:modelValue', innerDataList.value)

		// 判断是否还有更多数据
		noMore.value = newData.length < props.pageSize || innerDataList.value.length >= total

		// 重置加载状态
		isRefreshing.value = false
		isLoadingMore.value = false
		
		isFirstPageLoad.value = false
	}

	// 暴露给父组件的方法：请求失败时调用
	const fail = () => {
		if (currentPage.value > 1) {
			currentPage.value-- // 加载失败时回退页码
		}
		isRefreshing.value = false
		isLoadingMore.value = false
	}

	// 暴露给父组件的方法：手动重新加载
	const reload = () => {
		currentPage.value = 1
		noMore.value = false
		emit('refresh', currentPage.value, props.pageSize)
	}

	// 将方法暴露给父组件通过 ref 调用
	defineExpose({
		complete,
		fail,
		reload
	})

	// 初始自动加载
	if (props.autoLoad) {
		nextTick(() => {			
			emit('refresh', currentPage.value, props.pageSize)			
		})
	}
</script>

<style scoped lang="scss">
	.cc-paging-scroll-view {
		height: 100%;
		position: relative;
		box-sizing: border-box;
	}

	.refresher-container {
		height: 80rpx;
		display: flex;
		flex-direction: row;
		align-items: center;
		justify-content: center;
		z-index: 100;
		gap: 10rpx;
	}

	.refresher-arrow-icon {
		width: 35rpx;
		height: 35rpx;
		transition: transform 0.3s ease;
		transition-duration: .2s;
		transition-property: transform;

		&.arrow-top {
			transform: rotate(0deg);
		}

		&.arrow-down {
			transform: rotate(180deg);
		}
	}

	.refresher-loading-icon {
		width: 35rpx;
		height: 35rpx;
		/* 旋转动画 */
		animation: rotating 2s linear infinite;
	}

	.refresher-text {
		z-index: 10;
		position: relative;
		font-size: 28rpx;
		color: #666;
	}

	.load-more-container {
		padding: 30rpx;
		text-align: center;
		background-color: #f7f7f7;
	}

	.load-more-text {
		font-size: 28rpx;
		color: #999;
	}
	
	.empty-container{
		height: 100%;
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	/* 旋转动画 */
	@keyframes rotating {
		from {
			transform: rotate(0deg);
		}

		to {
			transform: rotate(360deg);
		}
	}
</style>